package znyl.nursing.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.poi.util.Internal;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import znyl.common.exception.base.BaseException;
import znyl.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import znyl.nursing.domain.*;
import znyl.nursing.dto.CheckInApplyDto;
import znyl.nursing.dto.ElderFamilyDto;
import znyl.nursing.mapper.BedMapper;
import znyl.nursing.mapper.CheckInMapper;
import znyl.nursing.mapper.ContractMapper;
import znyl.nursing.mapper.ElderMapper;
import znyl.nursing.service.IBedService;
import znyl.nursing.service.ICheckInConfigService;
import znyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import znyl.nursing.service.IContractService;
import znyl.nursing.util.CodeGenerator;
import znyl.nursing.util.IDCardUtils;
import znyl.nursing.vo.CheckInConfigVo;
import znyl.nursing.vo.CheckInDetailVo;
import znyl.nursing.vo.CheckInElderVo;
import znyl.nursing.vo.ElderFamilyVo;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 * 
 * @author 睢高浩
 * @date 2025-10-28
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private IBedService bedService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private ICheckInService checkInService;
    @Autowired
    private ICheckInConfigService checkInConfigService;
    @Autowired
    private ContractMapper contractMapper;


    /**
     * 查询入住
     * 
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住列表
     * 
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return checkInMapper.insertCheckIn(checkIn);
    }

    /**
     * 修改入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn) == true ? 1 : 0;
    }

    /**
     * 批量删除入住
     * 
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) == true ? 1 : 0;
    }

    /**
     * 删除入住信息
     * 
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id) == true ? 1 : 0;
    }

    /**
     * 入住申请
     * @param checkIn
     */
    @Override
    @Transactional
    public void apply(CheckInApplyDto checkIn) {
        //判断老人是否已经入住
        //根据入住中的的老人身份证号查询老人是否入住
        LambdaQueryWrapper<Elder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Elder::getIdCardNo,checkIn.getCheckInElderDto().getIdCardNo())
                .eq(Elder::getStatus,1);
        Elder elderDb1 = elderMapper.selectOne(queryWrapper);
        if(ObjectUtils.isNotEmpty(elderDb1)){
            throw new BaseException("该老人已经入住！");
        }

        //更新床位状态
        //判段床位
        Long bedId = checkIn.getCheckInConfigDto().getBedId();
        Bed beda = bedService.selectBedById(bedId); // 先查询床位，确认存在
        if (ObjectUtils.isEmpty(beda)) {
            throw new BaseException("指定床位不存在，无法完成入住！");
        }
        // 若床位已被占用，可额外增加校验（可选，增强健壮性）
        if (beda.getBedStatus() == 1) {
            throw new BaseException("该床位已被占用，请选择其他床位！");
        }
        LambdaUpdateWrapper<Bed> updateChainWrapper = new LambdaUpdateWrapper();
        updateChainWrapper.eq(Bed::getId,checkIn.getCheckInConfigDto().getBedId())
                .set(Bed::getBedStatus,1);
        bedService.update(updateChainWrapper);

        //新增或更新老人
        //判断老人是否已经入住
        LambdaQueryWrapper<Elder> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(Elder::getIdCardNo, checkIn.getCheckInElderDto().getIdCardNo())
                .eq(Elder::getStatus, 0);
        Elder elderDb = elderMapper.selectOne(queryWrapper1);
        Elder elder = new Elder();
        BeanUtils.copyProperties(checkIn.getCheckInElderDto(), elder);
        Bed bed = bedService.selectBedById(checkIn.getCheckInConfigDto().getBedId());
        elder.setBedNumber(bed.getBedNumber());
        elder.setBedId(bed.getId());
        elder.setStatus(1);
        if (ObjectUtils.isNotEmpty(elderDb)) {
            elder.setId(elderDb.getId()); // 用已有老人的ID，避免重复
            elderMapper.updateById(elder);
        } else {
            elderMapper.insert(elder);
        }

        //新增签约办理
        //生成合同编号
        String contractNo = "HT"+CodeGenerator.generateContractNumber();
        Contract contract = new Contract();
        //属性拷贝
        BeanUtils.copyProperties(checkIn.getCheckInContractDto(),contract);
        contract.setContractNumber(contractNo);
        //查询修改后的老人信息！
        LambdaQueryWrapper<Elder> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(Elder::getIdCardNo,checkIn.getCheckInElderDto().getIdCardNo());
        Elder elder1 = elderMapper.selectOne(queryWrapper2);
        contract.setElderId(elder1.getId());
        contract.setElderName(elder1.getName());
        //状态、开始时间、结束时间
        //签约时间小于等于当前时间，合同生效中
        LocalDateTime startDate = checkIn.getCheckInConfigDto().getStartDate();//开始时间
        LocalDateTime endDate = checkIn.getCheckInConfigDto().getEndDate();
        Integer status = startDate.isAfter(LocalDateTime.now()) ? 1 : 0;
        contract.setStatus(status);
        contract.setStartDate(startDate);
        contract.setEndDate(endDate);
        contractService.save(contract);
        //新增入住信息
        CheckIn checkIn2 = new CheckIn();
        checkIn2.setElderName(elder1.getName());
        checkIn2.setElderId(elder1.getId());
        checkIn2.setIdCardNo(elder1.getIdCardNo());
        checkIn2.setBedNumber(elder1.getBedNumber());
        checkIn2.setStartDate(startDate);
        checkIn2.setEndDate(endDate);
        checkIn2.setNursingLevelName(checkIn.getCheckInConfigDto().getNursingLevelName());
        checkIn2.setStatus(0);
        checkIn2.setRemark(JSON.toJSONString(checkIn.getElderFamilyDtoList()));
        checkInService.save(checkIn2);
        //新增入住配置信息
        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkIn.getCheckInConfigDto(),checkInConfig);
        //查询一下当前老人的入住信息
        LambdaQueryWrapper<CheckIn> checkInQueryWrapper = new LambdaQueryWrapper<>();
        checkInQueryWrapper.eq(CheckIn::getElderId, elder1.getId());
        checkInQueryWrapper.eq(CheckIn::getStatus, 0);
        CheckIn checkIn3 = checkInMapper.selectOne(checkInQueryWrapper);
        checkInConfig.setCheckInId(checkIn3.getId());
        checkInConfigService.save(checkInConfig);
    }

    /**
     * @param id
     * @return 查看申请详细信息
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        //查询入住信息
        CheckIn checkIn = checkInService.getById(id);
        if (checkIn == null){
            throw new BaseException("入住信息不存在！");
        }
        //查询老人信息
        Elder elder = elderMapper.selectElderById(checkIn.getElderId());
        if (elder == null){
            throw new BaseException("老人信息不存在！");
        }
        CheckInElderVo checkInElderVo = new CheckInElderVo();
        BeanUtils.copyProperties(elder,checkInElderVo);
        //计算年龄
        if (elder != null && elder.getIdCardNo() != null) {
            Integer elderAge = IDCardUtils.getAgeByIdCard(elder.getIdCardNo());
            checkInElderVo.setAge(elderAge);
        }
        checkInDetailVo.setCheckInElderVo(checkInElderVo);
        System.out.println("老人信息："+checkInElderVo);
        //查询合同信息（根据老人id查询）
        LambdaQueryWrapper<Contract> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Contract::getElderId,elder.getId());
        Contract contract = contractMapper.selectOne(queryWrapper);
        System.out.println(contract);
        if (contract == null){
            throw new BaseException("合同信息不存在！");
        }
        checkInDetailVo.setContract(contract);
        //查询入住配置信息
        LambdaQueryWrapper<CheckInConfig> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(CheckInConfig::getCheckInId,checkIn.getId());
        CheckInConfig checkInConfig = checkInConfigService.getOne(queryWrapper1);
        if (checkInConfig == null){
            throw new BaseException("入住配置信息不存在！");
        }
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        BeanUtils.copyProperties(checkInConfig,checkInConfigVo);
        //从配置信息中获取开始时间可结束时间
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        //根据老人表中的床位id查询床位的bed_number
        LambdaQueryWrapper<Bed> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(Bed::getId,elder.getBedId());
        Bed bed = bedService.getOne(queryWrapper2);
        checkInConfigVo.setBedNumber(bed.getBedNumber());
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);
        //将Remark中的JSON转换成ElderFamilyVo
        checkInDetailVo.setElderFamilyVoList(JSON.parseArray(checkIn.getRemark(), ElderFamilyVo.class));
        return checkInDetailVo;
    }

}
